package com.cj.controller;

import com.cj.pojo.Result;
import com.cj.pojo.User;
import com.cj.pojo.dto.AvatarUpdateDTO;
import com.cj.pojo.dto.RoleUpdateDTO;
import com.cj.pojo.dto.StatusUpdateDTO;
import com.cj.pojo.dto.UserQueryDTO;
import com.cj.pojo.dto.UserUpdateDTO;
import com.cj.pojo.dto.UserUpdateRequestDTO;
import com.cj.pojo.PageBean;
import com.cj.service.UserService;
import com.cj.utils.JwtUtil;
import com.cj.utils.Md5Util;
import com.cj.utils.ThreadLocalUtil;
import com.cj.exception.BaseException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Pattern;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import org.springframework.http.MediaType;

/*
 * 用户控制器
 */
@RestController
@RequestMapping("/api/user")
@Validated
public class UserController {

    @Autowired
    private UserService userService;
    private final Logger logger = LoggerFactory.getLogger("sys-user");

    // 注册用户
    @PostMapping(value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result register(@RequestBody @Valid RegisterDTO registerDTO) {
        logger.info("Register request received for username: {}", registerDTO.getUsername());
        try {
            userService.register(registerDTO.getUsername(), registerDTO.getPassword());
            return Result.success();
        } catch (BaseException e) {
            return Result.error(e.getErrorCode(), e.getMessage());
        }
    }

    public static class RegisterDTO {
        @Pattern(regexp = "^\\S{5,16}$")
        private String username;

        @Pattern(regexp = "^\\S{5,16}$")
        private String password;

        // getters and setters
        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    // 登录
    @PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Result<String> login(@RequestBody LoginDTO loginDTO) {
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        
        // 参数校验
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            logger.warn("登录参数校验失败: username={}", username);
            return Result.error("用户名和密码不能为空");
        }
        
        try {
            logger.info("用户尝试登录: {}", username);
            // 使用服务层验证
            User loginUser = userService.login(username, password);
            
            // 生成JWT token
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", loginUser.getId());
            claims.put("username", loginUser.getUsername());
            String token = JwtUtil.genToken(claims);
            
            logger.info("用户登录成功: {}", username);
            return Result.success(token);
        } catch (BaseException e) {
            logger.error("用户登录失败: {}, 原因: {}, 异常堆栈: ", username, e.getMessage(), e);
            return Result.error(e.getErrorCode(), e.getMessage());
        }
    }

    @GetMapping("/userInfo")
    public Result<User> userInfo(/*@RequestHeader(name = "Authorization") String token*/) {
        //根据用户名查询用户
        /* Map<String, Object> map = JwtUtil.parseToken(token);
        String username = (String) map.get("username");*/
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User user = userService.findByUserName(username);
        return Result.success(user);
    }

    @PutMapping("/update")
    public Result update(@RequestBody @Validated UserUpdateRequestDTO updateDTO, 
    @RequestHeader("Authorization") String token) {
        Map<String, Object> claims = JwtUtil.parseToken(token);
        Integer id = (Integer) claims.get("id");
        userService.updateUserInfo(id, updateDTO);
        return Result.success();
    }

    @PutMapping("/updateInfo") 
    public Result updateUserInfo(@Valid @RequestBody UserUpdateDTO userUpdateDTO, 
    @RequestHeader("Authorization") String token) {
        Map<String, Object> claims = JwtUtil.parseToken(token);
        Long userId = ((Integer) claims.get("id")).longValue();
        userService.updateUserInfo(userId, userUpdateDTO);
        return Result.success();
    }

    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestBody @Validated AvatarUpdateDTO avatarDTO) {
        userService.updateAvatar(avatarDTO.getAvatarUrl());
        return Result.success();
    }

    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String, String> params,@RequestHeader("Authorization") String token) {
        //1.校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("缺少必要的参数");
        }

        //原密码是否正确
        //调用userService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUserName(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!rePwd.equals(newPwd)){
            return Result.error("两次填写的新密码不一样");
        }

        //2.调用service完成密码更新
        userService.updatePwd(newPwd);
        // token删除逻辑已移除(本地学习不需要Redis)
        return Result.success();
    }

    @PatchMapping("/status")
    public Result updateStatus(@RequestBody @Validated StatusUpdateDTO statusDTO) {
        userService.updateStatus(statusDTO.getId(), statusDTO.getStatus());
        return Result.success();
    }

    //
    @PatchMapping("/role")
    public Result updateRole(@RequestBody @Validated RoleUpdateDTO roleDTO) {
        userService.updateRole(roleDTO.getId(), roleDTO.getRole());
        return Result.success();
    }

    @PostMapping("/list")
    public Result<PageBean<User>> listUsers(@RequestBody @Validated UserQueryDTO queryDTO) {
        PageBean<User> pb = userService.listUsers(
            queryDTO.getPageNum(),
            queryDTO.getPageSize(),
            queryDTO.getStatus(),
            queryDTO.getRole()
        );
        return Result.success(pb);
    }

    @DeleteMapping("/{id}")
    public Result deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return Result.success();
    }

    public static class LoginDTO {
        @Pattern(regexp = "^\\S{5,16}$")
        private String username;

        @Pattern(regexp = "^\\S{5,16}$")
        private String password;

        // getters and setters
        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }
}
